/* << fastinsert report library >> GridBase.h Oct 31, 2010
 *
 * 	http://code.google.com/p/libfir
 *
 * Copyright (c) 2005 Pavlo Drobov (drobov.pavel@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */


#ifndef GRIDBASE_H_
#define GRIDBASE_H_

#include "win32_export_macros.h"

#include "IGrid.h"

#include "Text.h"
#include "PdfBase.h"

#include <list>


namespace dasco
{
namespace report
{

//! \struct ACell
//! \brief TODO: describe me
template <typename T>
struct ACell
	:ICell
	,Text
{
	explicit
	ACell(T arg)
		:Text(arg)
		,value(arg)
	{
		cellType = CellText;
		//TODO check it
		//value = text;
	}

	virtual ~ACell(){}

	T value;

	//ICell iface
	unsigned getLength() const {return Text::getLength();};
	operator const char* () const { return text;}
	const char* asText() const {return text;}
	//end ICell iface
};

//! \struct Cell
//! \brief TODO: describe me
template <typename T>
struct Cell : ACell<T>
{
	explicit
	Cell(T __value)
		: ACell<T>(__value){}
};

//! \struct Cell
//! \brief TODO: describe me
template <>
struct Cell<int>
	:ACell<int>
{
	explicit
	Cell(int __value)
		:ACell<int>(__value)
	{
		cellType = CellInt;
	}

};

//! \struct Cell
//! \brief TODO: describe me
template <>
struct Cell<float>
	:ACell<float>
{
	explicit
	Cell(float __value)
		:ACell<float>(__value)
	{
		cellType = CellFloat;
	}
};


//! \struct StdList
//! \brief TODO: describe me
template<typename T>
struct DLL_EXPORT StdList
	: IIterator<T>
	, std::list<T>

{
	virtual ~StdList()
	{
		setIteratorToBegin();
		while(midge != race_over_for_midge)
			delete *midge++;
	}

	//IIterator iface
	IIterator<T>& operator ++(int)
	{
		IIterator<T>& rc = *this;
		if(midge != race_over_for_midge)
			midge++;
		return rc;
	}

	operator T()
	{
		return midge != race_over_for_midge ? *midge : NULL;
	}

	T  operator -> ()
	{
		return midge != race_over_for_midge ? *midge : NULL;
	}
	//end IIterator iface

	void setIteratorToBegin() const
	{
		midge = std::list<T>::begin();
		race_over_for_midge = std::list<T>::end();
	}

	mutable typename std::list<T>::const_iterator midge, race_over_for_midge;
};


/////////////////////////
typedef IIterator<ICell*>& iteratorICell;

class DLL_EXPORT RowSet
	:virtual public IRowSet
	,private StdList<ICell*>
{
	friend class GridBase;
public:
	RowSet(const char* = NULL);
	virtual ~RowSet();

	//implement IOutline iface
	const char* asText() const {return outline;}
	//end IOutline iface

	//implement IRowSet iface
	void addColumn(const int value){addColumnT(value);}
	void addColumn(const float value){addColumnT(value);}
	void addColumn(const char* value){addColumnT(value);}
	unsigned cellQuantity() const {return size();}
	//end IRowSet iface


	//implement ICollection iface
	iteratorICell getIterator()
	{
		setIteratorToBegin();
		return *this;
	}
	//end ICollection iface

	ICell* operator [] (unsigned) const;
	ICell* at (unsigned) const;


protected:
	Text outline;

private:
	template<typename T>
	void addColumnT(T value)
	{
		push_back(new Cell<T>(value));
	}
};

class DLL_EXPORT RowSetHeader
	:public RowSet
	,public IRowSetHeader
{
public:
	RowSetHeader(const char* = NULL);
	virtual ~RowSetHeader(){}
};


/////////////////////////////////
typedef IIterator<IRowSet*>& iteratorIRowSet;

class DLL_EXPORT GridBase
	:public IGrid
	,private StdList<IRowSet*>
{
public:
	GridBase(const char* = NULL);
	virtual ~GridBase();

	//implement IOutline iface
	const char* asText() const {return outline;}
	//end IOutline iface


	//IGrid iface
	DLL_EXPORT void addRow(IRowSet*);
	//end IGrid iface

	//ICollection iface
	iteratorIRowSet getIterator()
	{
		setIteratorToBegin();
		return *this;
	}
	//end ICollection iface

protected:
	Text outline;

};

}} //dasco::report

#endif /* GRIDBASE_H_ */

